﻿// Original author contact info: Owen Emlen (owene_1998@yahoo.com)
// Note: other individuals may also have contributed to this code
// Project hosted on CodePlex.com as of 1/10/2009 at http://wpfimageviewer.codeplex.com
using System;
using System.Windows;
using System.Windows.Controls;
using System.Linq;
using BrainTechLLC;
using BrainTechLLC.FolderExplorer;
using DragDropLibrary;
using ImageAppDataModels;
using System.ComponentModel;
using DirectoryViewModels;
using System.Diagnostics;
using System.Drawing;

namespace FolderView.Plugin
{
    /// <summary>
    /// Interaction logic for FolderExplorerWindow.xaml
    /// </summary>
    public partial class FolderExplorerWindow : Window, INotifyPropertyChanged
    {
        public event EventHandler WantClose;
        public event EventHandler<ObjectEventArgs<FolderViewModel>> SelectFoldersStart;
        public event EventHandler<ObjectEventArgs<FolderViewModel>> SelectFoldersEnd;

        public FolderExplorerWindow()
        {
            InitializeComponent();            
            Closing += new System.ComponentModel.CancelEventHandler(FolderExplorerWindow_Closing);
            DragAndDrop.DropCompleted += new EventHandler<DropEventArgs<object>>(DragAndDrop_DropCompleted);
            DragAndDrop.BeginDrag += new EventHandler<ObjectEventArgs<ItemsControl, object>>(DragAndDrop_BeginDrag);
            Loaded += new RoutedEventHandler(FolderExplorerWindow_Loaded);
        }

        void FolderExplorerWindow_Loaded(object sender, RoutedEventArgs e)
        {
            folderExplorer.RootFolder = new FolderViewModel(FolderExplorerWindowHandler.Handler.Handler.DirectoriesToExamineViewModel, null);
            var f = folderExplorer.RootFolder;
            //f.PropertyChanged += new PropertyChangedEventHandler(f_PropertyChanged);
            f.ClearSubfolders += new EventHandler(f_ClearSubfolders);
            f.SubfoldersPopulated += new EventHandler(f_SubfoldersPopulated);
            WireSubfolders(f);
            cboFolders.ItemsSource = f.SpecialFolders;
            this.DataContext = f;
            settingsMenu.DataContext = this;
            if (f.SpecialFolders.Count > 1)
            {
                Dispatcher.BeginInvoke(new VoidDelegate(() => cboFolders.SelectedIndex = 1));
            }
        }

        protected void OnPropertyChanged(string propertyName)
        {
            PropertyChanged.RaiseEvent(this, propertyName);
        }

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        public static readonly DependencyProperty TextSizeProperty =
            DependencyProperty.Register("TextSize", typeof(double), typeof(FolderExplorerWindow), new PropertyMetadata(9.0, OnTextSizePropertyChanged));

        public double TextSize
        {
            get { return (double)GetValue(TextSizeProperty); }
            set { SetValue(TextSizeProperty, value); }
        }

        private static void OnTextSizePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            FolderExplorerWindow source = d as FolderExplorerWindow;
            double v = (double)e.NewValue;
            source.UpdateTextSize(v);
        }

        private void UpdateTextSize(double val)
        {
            UpdateUI();
            OnPropertyChanged("TextSize");    
        }

        public void UpdateUI()
        {
            folderExplorer.FontSize = TextSize;
            this.Topmost = AlwaysOnTop;
        }

        public static readonly DependencyProperty AlwaysOnTopProperty =
            DependencyProperty.Register("AlwaysOnTop", typeof(bool), typeof(FolderExplorerWindow), new PropertyMetadata(true, OnAlwaysOnTopPropertyChanged));

        public bool AlwaysOnTop
        {
            get { return (bool)GetValue(AlwaysOnTopProperty); }
            set { SetValue(AlwaysOnTopProperty, value); }
        }

        private static void OnAlwaysOnTopPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            FolderExplorerWindow source = d as FolderExplorerWindow;
            bool v = (bool)e.NewValue;
            source.UpdateAlwaysOnTop(v);
        }

        private void UpdateAlwaysOnTop(bool val)
        {
            UpdateUI();
            OnPropertyChanged("AlwaysOnTop");
        }        

        private void WireSubfolders(FolderViewModel f)
        {
            if (f.SubFoldersCached != null)
            {
                var v = from folder in f.SubFoldersCached.AsParallel()
                        select folder;

                v.ForAll(folder =>
                {
                    // folder.PropertyChanged += new PropertyChangedEventHandler(f_PropertyChanged);
                    folder.ClearSubfolders += new EventHandler(f_ClearSubfolders);
                    folder.SubfoldersPopulated += new EventHandler(f_SubfoldersPopulated);
                });
            }
        }

        void f_SubfoldersPopulated(object sender, EventArgs e)
        {
            FolderViewModel f = sender as FolderViewModel;
            WireSubfolders(f);
        }

        //void f_PropertyChanged(object sender, PropertyChangedEventArgs e)
        //{
        //    FolderViewModel f = sender as FolderViewModel;
        //    //WriteLog(string.Format("FolderViewModel {0}: {1}", f.Name, e.PropertyName));
        //}

        void f_ClearSubfolders(object sender, EventArgs e)
        {
            FolderViewModel f = sender as FolderViewModel;
            UnwireSubfolders(f);
        }

        private void UnwireSubfolders(FolderViewModel f)
        {
            if (f.SubFoldersCached != null)
            {
                foreach (var folder in f.SubFoldersCached)
                {
                    folder.SubfoldersPopulated -= f_SubfoldersPopulated;
                    folder.ClearSubfolders -= f_ClearSubfolders;
                    // folder.PropertyChanged -= f_PropertyChanged;
                }
            }
        }

        private void cboFolders_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (cboFolders.SelectedItem != null)
            {
                string folderName = cboFolders.SelectedItem as string;
                Debug.WriteLine(cboFolders.SelectedItem.ToString());
                folderExplorer.RootFolder.SelectedSpecialFolder = folderName;
            }
        }

        // an item was dropped successfully to another control
        void DragAndDrop_DropSuccessful(object sender, ObjectEventArgs<ItemsControl, object> e)
        {
            DragAndDrop.DropSuccessful -= DragAndDrop_DropSuccessful;

            FolderViewModel folder = e.obj1.Tag as FolderViewModel;

            if (folder != null)
            {
                folder.ClearFiles();
            }
        }

        // user begins dragging an item out of the folder explorer control
        void DragAndDrop_BeginDrag(object sender, ObjectEventArgs<ItemsControl, object> e)
        {
            if (BrainTechLLC.WPF.TempExten.FindParent<FolderExplorerControl>(e.obj1) != null)
            {
                DragAndDrop.DropSuccessful += new EventHandler<ObjectEventArgs<ItemsControl, object>>(DragAndDrop_DropSuccessful);
            }
        }

        // user is dropping data here
        void DragAndDrop_DropCompleted(object sender, DropEventArgs<object> e)
        {
            if (DragAndDrop.GetRegisterDropTargetName(e.DroppedOnto) == "FileListView")
            {
                FolderExplorerWindowHandler.Handler.Handler.RaiseDropData(e.Object, e.DragSource, e.DroppedOnto);
            }
            else if (DragAndDrop.GetRegisterDropTargetName(e.DroppedOnto) == "TreeView")
            {
                FolderExplorerWindowHandler.Handler.Handler.RaiseDropData(e.Object, e.DragSource, e.DroppedOnto);
            }
        }

        void FolderExplorerWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            Closing -= FolderExplorerWindow_Closing;
            DragAndDrop.DropCompleted -= DragAndDrop_DropCompleted;
            DragAndDrop.BeginDrag -= DragAndDrop_BeginDrag;
        }

        private void btnSelectFolders_Click(object sender, RoutedEventArgs e)
        {
            WantClose.RaiseEvent(this);
        }

        private void Window_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            SaveSizeAndLocation();
        }

        private void Window_Closing(object sender, CancelEventArgs e)
        {
            SaveSizeAndLocation();
        }

        public void WireUpSizeAndLocationChanged()
        {
            SizeChanged -= Window_SizeChanged;
            LocationChanged -= Window_LocationChanged;
            SizeChanged += new SizeChangedEventHandler(Window_SizeChanged);
            LocationChanged += new EventHandler(Window_LocationChanged);
        }

        public void SaveSizeAndLocation()
        {
            if (Settings.Values.FolderExplorerVisible && this.ActualWidth > 0 && this.ActualHeight > 0)
            {
                if (this.WindowState == System.Windows.WindowState.Normal)
                {
                    Settings.Values.FolderExplorerWindowState = System.Windows.WindowState.Normal;
                    Settings.Values.FoldersViewLocation = new Rectangle((int)this.Left, (int)this.Top, (int)this.ActualWidth, (int)this.ActualHeight);
                }
                else if (this.WindowState == System.Windows.WindowState.Maximized)
                {
                    Settings.Values.FolderExplorerWindowState = System.Windows.WindowState.Maximized;
                }
            }
        }

        private void Window_LocationChanged(object sender, EventArgs e)
        {
            SaveSizeAndLocation();
        }

        private void txtSearch_TextChanged(object sender, TextChangedEventArgs e)
        {
            folderExplorer.MarkSearchTextChanged(txtSearch.Text);
        }

        private void chkShowFolderAndFiles_Checked(object sender, RoutedEventArgs e)
        {
            folderExplorer.ShowFilesAndFolders = true;
        }

        private void chkShowFolderAndFiles_Unchecked(object sender, RoutedEventArgs e)
        {
            folderExplorer.ShowFilesAndFolders = false;
        }

        void OperationHandler_SelectFoldersEnd(object sender, ObjectEventArgs<FolderViewModel> e)
        {
            SelectFoldersEnd.RaiseEvent(this, e.obj);            
        }

        void OperationHandler_SelectFoldersStart(object sender, ObjectEventArgs<FolderViewModel> e)
        {
            SelectFoldersStart.RaiseEvent(this, e.obj);
        }
    }
}
